上層元件要傳給子層元件資料,是用 props 來傳遞,若子層元件有很多層,而最底層元件需要該資料,無論中間的元件有沒有使用到,都必需一層一層的傳 props。
const App = () => {
const [user, setUser] = React.useState("Lala");
return (
<>
<h1>{`Hello ${user}!`}</h1>
<Component1 user={user} />
</>
);
};
const Component1 = ({ user }) => {
return (
<>
<h1>Component 1</h1>
<Component2 user={user} />
</>
);
};
const Component2 = ({ user }) => {
return (
<>
<h1>Component 2</h1>
<Component3 user={user} />
</>
);
};
const Component3 = ({ user }) => {
return (
<>
<h1>Component 3</h1>
<h2>{`Hello ${user} again!`}</h2>
</>
);
};
每層傳遞 props,就算 Componet1 跟 Componet2 用不到
也必需層層傳遞 props 至需要使用的 Component3
透過 Context 的概念,可以將資料傳到直接傳送到需要的元件,而不需要手動一直透過 props 傳入。
使用 Context API 有三個步驟
const xxxContext = createContext();
<xxxContext.Provider value={要給Context範圍內元件使用的值}>
...
</xxxContext.Provider>
const data = useContext(xxxContext);
Step 1. 建立 Context 物件內容
const UserContext = createContext();
Step 2. 提供 Context Provider,把要使用 Context 資訊的元件使用 <xxxContext.Provider>
包起來
這邊要傳的是資料是 user,所以 value 放的是 user
const App = () => {
const [user, setUser] = useState("lala");
return (
<UserContext.Provider value={user}>
<h1>{`Hello ${user}!`}</h1>
<Component2 />
</UserContext.Provider>
);
}
Step 3. 在 Function Component 中使用 Context - useContext
const Component3 = () => {
const user = useContext(UserContext);
return (
<>
<h1>Component 5</h1>
<h2>{`Hello ${user} again!`}</h2>
</>
);
}
完整組合如下
const UserContext = React.createContext();
const App = () => {
const [user, setUser] = React.useState("lala");
return (
<UserContext.Provider value={user}>
<h1>{`Hello ${user}!`}</h1>
<Component2 />
</UserContext.Provider>
);
}
const Component1 = ({ user }) => {
return (
<>
<h1>Component 1</h1>
<Component2 />
</>
);
};
const Component2 = ({ user }) => {
return (
<>
<h1>Component 2</h1>
<Component3 />
</>
);
};
const Component3 = () => {
const user = React.useContext(UserContext);
return (
<>
<h1>Component 3</h1>
<h2>{`Hello ${user} again!`}</h2>
</>
);
};
Context 有一個致命的缺點,當 Context 資料更新時,會讓所有在 Context 範圍內中的元件都會 Re-Render,所以不會經常變動的內容才比較使用 Context 來做資料的共享。像是「使用者的登入狀態」、「樣式(theme)」、「語系切換(preferred language)」等。
如果我們希望元件之間共享資料,使用 props 層層傳遞太麻煩,而使用 Context 又會有效能上的問題,那還有什麼方式可以達成?
在大型的應用上,都會引入 Redux 這個第三方提供的狀態管理套件來操作。接下來會開始深入探討 Redux 這個主題。
https://www.w3schools.com/react/react_usecontext.asp
https://pjchender.dev/react/react-doc-context/
https://medium.com/hannah-lin/react-hook-%E7%AD%86%E8%A8%98-usecontext-4bc289976847